package www.wen.com.common.lib.util;

import com.orhanobut.logger.Logger
import java.util.regex.Pattern

/**
 * @author WEN
 * @Description:
 * @date 2021/2/18 10:11
 */
object CheckEncodingUtil {


    /**
     * 生成正确的EAN13码
     */
    fun generateCorrectEAN13(code: String): String {
        //使用0替换非数字字符串
        var newCode = code.replace("[^\\d]".toRegex(), "0")
        //截取前13位字符串并校验是否为正确的EAN13条形码,否则生成第13位校验码并替换
        if (newCode.length >= 13) {
            newCode = newCode.substring(0, 13)
            val chars = newCode.toCharArray()
            var total1 = 0
            var total2 = 0
            for (index in chars.indices) {
                val charNumber = Integer.parseInt(chars[index].toString())
                if (index >= 1 && index % 2 != 0) {
                    total1 += charNumber
                }
                if (index >= 0 && index % 2 == 0) {
                    total2 += charNumber
                }
            }
            val s = if ((10 - (total1 * 3 + total2) % 10) == 10) 0 else 10 - (total1 * 3 + total2) % 10
            val s1 = Integer.parseInt(chars[12].toString())
            return if (s == s1) {
                newCode
            } else {
                val sb = StringBuilder(newCode)
                newCode = sb.replace(12, 12, s.toString()).toString()
                newCode
            }
        }
        //不足12位字符串用0替代并生成第13位校验码
        if (newCode.length < 13) {
            for (index in 0..12) {
                if (newCode.length == 12) {
                    val chars = newCode.toCharArray()
                    var total1 = 0
                    var total2 = 0
                    for (indexA in chars.indices) {
                        val charNumber = Integer.parseInt(chars[indexA].toString())
                        if (indexA >= 1 && indexA % 2 != 0) {
                            total1 += charNumber
                        }
                        if (indexA >= 0 && indexA % 2 == 0) {
                            total2 += charNumber
                        }
                    }
                    val sum = total1 * 3 + total2
                    val s = if ((10 - (sum) % 10) == 10) 0 else (10 - (sum) % 10)
                    newCode += s
                    break
                } else {
                    newCode += "0"
                }
            }
        }
        return newCode
    }

    /**
     * 生成正确的EAN8码
     */
    fun generateCorrectEAN8(code: String): String {
        //使用0替换非数字字符串
        var newCode = code.replace("[^\\d]".toRegex(), "0")
        //截取前8位字符串并校验是否为正确的EAN13条形码,否则生成第13位校验码并替换
        if (newCode.length >= 8) {
            newCode = newCode.substring(0, 8)
            val code7 = newCode.substring(0, 7)
            val chars = code7.toCharArray()
            var total1 = 0
            var total2 = 0
            for (index in chars.indices) {
                val charNumber = Integer.parseInt(chars[index].toString())
                if (index % 2 == 0) {
                    total1 += charNumber
                }
                if (index % 2 != 0) {
                    total2 += charNumber
                }
            }
            val s = if ((10 - (total1 * 3 + total2) % 10) == 10) 0 else 10 - (total1 * 3 + total2) % 10
            val s1 = Integer.parseInt(newCode[7].toString())
            return if (s == s1) {
                newCode
            } else {
                val sb = StringBuilder(newCode)
                newCode = sb.replace(7, 8, s.toString()).toString()
                newCode
            }
        }
        //不足12位字符串用0替代并生成第13位校验码
        if (newCode.length < 8) {
            for (index in 0..7) {
                if (newCode.length == 7) {
                    val chars = newCode.toCharArray()
                    var total1 = 0
                    var total2 = 0
                    for (indexA in chars.indices) {
                        val charNumber = Integer.parseInt(chars[indexA].toString())
                        if (indexA % 2 == 0) {
                            total1 += charNumber
                        }
                        if (indexA % 2 != 0) {
                            total2 += charNumber
                        }
                    }
                    val sum = total1 * 3 + total2
                    val s = if ((10 - (sum) % 10) == 10) 0 else (10 - (sum) % 10)
                    newCode += s
                    break
                } else {
                    newCode += "0"
                }
            }
        }
        return newCode
    }


    /**
     * 生成正确的UPCA码
     */
    private fun generateCorrectUPCA(code: String): String {
        //使用0替换非数字字符串
        var newCode = code.replace("[^\\d]".toRegex(), "0")
        //截取前13位字符串并校验是否为正确的EAN13条形码,否则生成第13位校验码并替换
        if (newCode.length >= 11) {
            newCode = newCode.substring(0, 11)
            val chars = newCode.toCharArray()
            var total1 = 0
            var total2 = 0
            for (index in chars.indices) {
                val charNumber = Integer.parseInt(chars[index].toString())
                if (index % 2 == 0) {
                    total1 += charNumber
                }
                if (index % 2 != 0) {
                    total2 += charNumber
                }
            }
            val s = if ((10 - (total1 * 3 + total2) % 10) == 10) 0 else 10 - (total1 * 3 + total2) % 10
            newCode += s
        } else {
            for (index in 0..11) {
                if (newCode.length == 11) {
                    val chars = newCode.toCharArray()
                    var total1 = 0
                    var total2 = 0
                    for (indexA in chars.indices) {
                        val charNumber = Integer.parseInt(chars[indexA].toString())
                        if (indexA % 2 == 0) {
                            total1 += charNumber
                        }

                        if (indexA % 2 != 0) {
                            total2 += charNumber
                        }
                    }
                    val sum = total1 * 3 + total2
                    val s = if ((10 - (sum) % 10) == 10) 0 else (10 - (sum) % 10)
                    newCode += s
                    break
                } else {
                    newCode += "0"
                }
            }
        }
        return newCode
    }

    fun checkIsEAN13New(code: String, result: ((Boolean, String) -> Unit)? = null) {
        if (!isNumeric(code)) {
            result?.invoke(false, generateCorrectEAN13(code))
        } else if (code.length == 13) {
            val chars = code.toCharArray()
            var total1 = 0
            var total2 = 0
            for (index in chars.indices) {
                val charNumber = Integer.parseInt(chars[index].toString())
                if (index >= 1 && index % 2 != 0) {
                    total1 += charNumber
                }
                if (index >= 0 && index % 2 == 0) {
                    total2 += charNumber
                }
            }
            val s = if ((10 - (total1 * 3 + total2) % 10) == 10) 0 else 10 - (total1 * 3 + total2) % 10
            val s1 = Integer.parseInt(chars[12].toString())
            if (s == s1) {
                result?.invoke(true, generateCorrectEAN13(code))
            } else {
                result?.invoke(false, generateCorrectEAN13(code))
            }
        } else if (code.length == 12) {
            result?.invoke(true, generateCorrectEAN13(code))
        } else {
            result?.invoke(false, generateCorrectEAN13(code))
        }
    }

    fun checkIsEAN8(code: String, result: ((Boolean, String) -> Unit)? = null) {
        if (!isNumeric(code)) {
            result?.invoke(false, generateCorrectEAN8(code))
        } else if (code.length == 8) {
            val chars = code.toCharArray()
            var total1 = 0
            var total2 = 0
            for (index in chars.indices) {
                val charNumber = Integer.parseInt(chars[index].toString())
                if (index % 2 != 0) {
                    total1 += charNumber
                }
                if (index % 2 == 0) {
                    total2 += charNumber
                }
            }
            val s = if ((10 - (total1 * 3 + total2) % 10) == 10) 0 else 10 - (total1 * 3 + total2) % 10
            val s1 = Integer.parseInt(chars[7].toString())
            if (s == s1) {
                result?.invoke(true, generateCorrectEAN8(code))
            } else {
                result?.invoke(false, generateCorrectEAN8(code))
            }
        } else if (code.length == 7) {
            result?.invoke(true, generateCorrectEAN8(code))
        } else {
            result?.invoke(false, generateCorrectEAN8(code))
        }
    }


    fun checkIsUPCA(code: String, result: ((Boolean, String) -> Unit)? = null) {
        if (!isNumeric(code)) {
            result?.invoke(false, generateCorrectUPCA(code))
        } else if (code.length == 12) {
            val chars = code.toCharArray()
            var total1 = 0
            var total2 = 0
            for (index in chars.indices) {
                val charNumber = Integer.parseInt(chars[index].toString())
                if (index % 2 == 0) {
                    Logger.i("奇数的值 = $charNumber")
                    total1 += charNumber
                }
                if (index % 2 != 0) {
                    Logger.i("偶数的值 = $charNumber")
                    total2 += charNumber
                }
            }
            val s = if ((10 - (total1 * 3 + total2) % 10) == 10) 0 else 10 - (total1 * 3 + total2) % 10
            val s1 = Integer.parseInt(chars[11].toString())
            Logger.i("奇数的总值 = $total1 , 偶数的总值 = $total2, 截取第12位校验码 = $s1 , 计算所得的第12位校验码 = $s")
            if (s == s1) {
                result?.invoke(true, generateCorrectUPCA(code))
            } else {
                result?.invoke(false, generateCorrectUPCA(code))
            }
        } else if (code.length == 11) {
            result?.invoke(true, generateCorrectUPCA(code))
        } else {
            result?.invoke(false, generateCorrectUPCA(code))
        }
    }


    /**
     * 检测字符串是否为纯数字
     */
    fun isNumeric(str: String): Boolean {
        val pattern: Pattern = Pattern.compile("[0-9]*")
        return pattern.matcher(str).matches()
    }

    /**
     * 检测是否ITF码
     */
    fun checkIsITF(code: String, result: ((Boolean, String) -> Unit)? = null) {
        if (!isNumeric(code)) {
            result?.invoke(false, generateCorrectITF(code))
            return
        }
        if (code.length % 2 != 0) {
            result?.invoke(false, generateCorrectITF(code))
            return
        }
        if (code.length > 80) {
            result?.invoke(false, generateCorrectITF(code))
            return
        }
        if (code.isEmpty()) {
            result?.invoke(false, generateCorrectITF(code))
            return
        }
        result?.invoke(true, generateCorrectITF(code))
    }


    /**
     * 生成正确的ITF码
     */
    private fun generateCorrectITF(code: String): String {
        //使用0替换非数字字符串
        var newCode = code.replace("[^\\d]".toRegex(), "0")
        //大于等于80位 截取前80位
        if (newCode.length > 80) {
            newCode = newCode.substring(0, 80)
        }
        //没有字符串则默认
        if (newCode.isEmpty()) {
            newCode = "00"
        }
        //如果不是偶数加多一位0
        if (newCode.length % 2 != 0) {
            val stringBuilder = StringBuffer(newCode)
            stringBuilder.insert(0, "0")
            newCode = stringBuilder.toString()
        }
        return newCode
    }

}